﻿namespace Atomic.Domain
{
    using System;

    /// <summary>
    /// 实体基类。
    /// </summary>
    public abstract class EntityBase : IEntity
    {
        /// <summary>
        /// Hash Code
        /// </summary>
        private int? _requestedHashCode = null;

        /// <summary>
        /// 初始化实体基类。
        /// </summary>
        public EntityBase()
            : this(0)
        {
        }

        /// <summary>
        /// 初始化实体基类。
        /// </summary>
        /// <param name="id">实体编号。</param>
        public EntityBase(int id)
        {
            this.Id = id;
        }

        /// <summary>
        /// 实体编号。
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 表示该实体是否是临时的。
        /// </summary>
        /// <returns>临时的则返回 true，否则返回 false。</returns>
        public bool IsTransient()
        {
            return this.Id <= 0;
        }

        /// <summary>
        /// 改变当前实体编号。
        /// </summary>
        /// <param name="identity">实体编号。</param>
        public void ChangeCurrentIdentity(int identity)
        {
            if (identity > 0)
                this.Id = identity;
        }

        #region Overrides Methods

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj == null || !(obj is EntityBase))
                return false;

            if (Object.ReferenceEquals(this, obj))
                return true;

            EntityBase item = (EntityBase)obj;

            if (item.IsTransient() || this.IsTransient())
                return false;
            else
                return item.Id == this.Id;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            if (!IsTransient())
            {
                if (!_requestedHashCode.HasValue)
                    _requestedHashCode = this.Id.GetHashCode() ^ 31;

                return _requestedHashCode.Value;
            }
            else
                return base.GetHashCode();

        }

        /// <summary>
        /// 重载“==”操作符
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static bool operator ==(EntityBase left, EntityBase right)
        {
            if (Object.Equals(left, null))
                return (Object.Equals(right, null)) ? true : false;
            else
                return left.Equals(right);
        }

        /// <summary>
        /// 重载“!=”操作符
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static bool operator !=(EntityBase left, EntityBase right)
        {
            return !(left == right);
        }

        #endregion
    }
}